/**
 * User: alesj
 * Date: 2004.8.23
 * Time: 15:28:54
 */

package com.generalynx.common.web.module;

import com.generalynx.ecos.data.dao.IBasicDAO;
import com.generalynx.ecos.data.dao.IBasicDAO;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.*;

/**
 * Static data about existing modules. Instantiated once at application start.
 */
public class Modules {

    protected final static Log logger = LogFactory.getLog(Modules.class);

    private static Modules instance;

    private Module root;
    private Map idModuleMap;
    private Map nameModuleMap;
    private List modulesList;
    private List modulesLeaves;

    public static Modules getInstance() {
        if (instance == null) {
            instance = new Modules();
        }
        return instance;
    }

    public void init(IBasicDAO basicDAO) {
        idModuleMap = new HashMap();
        nameModuleMap = new HashMap();
        root = basicDAO.loadRootModule(nameModuleMap, idModuleMap);
        logger.info("Module tree initialization successful.");
    }

    protected Module getRootModule() {
        return root;
    }

    protected Map getIdModuleMap() {
        return idModuleMap;
    }

    protected Map getNameModuleMap() {
        return nameModuleMap;
    }

    protected List getModulesList() {
        return modulesList;
    }

    protected void setModulesList(List modulesList) {
        this.modulesList = modulesList;
    }

    protected List getModulesLeaves() {
        return modulesLeaves;
    }

    protected void setModulesLeaves(List modulesLeaves) {
        this.modulesLeaves = modulesLeaves;
    }

    public static Module getModule(String name) {
        return (Module)getInstance().getNameModuleMap().get(name);
    }

    public static Module getModule(int id) {
        return (Module)getInstance().getIdModuleMap().get(new Integer(id));
    }

    public static Module getModule(Integer id) {
        return (Module)getInstance().getIdModuleMap().get(id);
    }

    public static Module getRoot() {
        if (getInstance().getRootModule() == null) {
            throw new NullPointerException("Root hasn't been initialized.");
        }
        return getInstance().getRootModule();
    }

    public static List getList() {
        if (getInstance().getModulesList() == null) {
            List modulesList = new ArrayList();

            Module root = getRoot();

            Stack stack = new Stack();
            stack.push(root);

            while (!stack.isEmpty()) {
                Module node = (Module)stack.pop();
                Iterator iter = node.getChildren().iterator();
                while (iter.hasNext()) {
                    Module child = (Module)iter.next();
                    modulesList.add(child);
                    stack.push(child);
                }
            }
            getInstance().setModulesList(modulesList);
        }
        return getInstance().getModulesList();
    }

    public static List getLeaves() {
        if (getInstance().getModulesLeaves() == null) {
            List modulesLeaves = new ArrayList();
            Iterator iter = getList().iterator();
            while (iter.hasNext()) {
                Module node = (Module)iter.next();
                if (node.getChildren().isEmpty())
                    modulesLeaves.add(node);
            }
            getInstance().setModulesLeaves(modulesLeaves);
        }
        return getInstance().getModulesLeaves();
    }
}

